summaryrefslogtreecommitdiff
path: root/src/app/api/company/[companyId]
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2026-02-12 10:25:19 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2026-02-12 10:25:19 +0700
commitd131b3cc79148b9f72a9bfe2fab3a0c6b3dd092d (patch)
tree898294dc44be11bdc92a6dc0f19027df5d7aa155 /src/app/api/company/[companyId]
parent706262222aeae50438fbfa8bcab05702fee35456 (diff)
<Miqdad> fix logicHEAD2026
Diffstat (limited to 'src/app/api/company/[companyId]')
-rw-r--r--src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx141
1 files changed, 69 insertions, 72 deletions
diff --git a/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx b/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx
index 1b641d3..8c7b377 100644
--- a/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx
+++ b/src/app/api/company/[companyId]/product/[productId]/compute-different/route.tsx
@@ -9,11 +9,12 @@ type PostParams = { params: { companyId: string; productId: string } };
const SELF_HOST = process.env.SELF_HOST as string;
export async function POST(request: NextRequest, { params }: PostParams) {
- const totalQty: { [key in keyof typeof Team]: number | 0 } = {
- COUNT1: 0,
- COUNT2: 0,
- COUNT3: 0,
- VERIFICATION: 0,
+ // Initial Condition
+ const totalQty: { [key in keyof typeof Team]: number | null } = {
+ COUNT1: null,
+ COUNT2: null,
+ COUNT3: null,
+ VERIFICATION: null,
};
const searchParams = new URLSearchParams({
@@ -21,93 +22,89 @@ export async function POST(request: NextRequest, { params }: PostParams) {
productId: params.productId.toString(),
});
- const stockOpnamesFetch = await fetch(`${SELF_HOST}/api/stock-opname/location?${searchParams}`);
+ const stockOpnamesFetch = await fetch(
+ `${SELF_HOST}/api/stock-opname/location?${searchParams}`,
+ );
const stockOpnames: StockOpnameLocationRes[] = await stockOpnamesFetch.json();
- let isDifferent: boolean = false;
- let verificationCounter: number = 0;
+ let verificationCounter = 0;
+ // =============================
+ // 2️⃣ ACCUMULATE QTY
+ // =============================
for (const opname of stockOpnames) {
- let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
+ const { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
- if (totalQty["COUNT1"] === null && _.isNumber(COUNT1.quantity)) totalQty["COUNT1"] = 0;
- if (totalQty["COUNT2"] === null && _.isNumber(COUNT2.quantity)) totalQty["COUNT2"] = 0;
- if (totalQty["COUNT3"] === null && _.isNumber(COUNT3.quantity)) totalQty["COUNT3"] = 0;
- if (totalQty["VERIFICATION"] === null && _.isNumber(VERIFICATION.quantity)) totalQty["VERIFICATION"] = 0;
+ const teams = { COUNT1, COUNT2, COUNT3, VERIFICATION };
- if (_.isNumber(COUNT1.quantity)) totalQty["COUNT1"] = (totalQty["COUNT1"] || 0) + COUNT1.quantity;
- if (_.isNumber(COUNT2.quantity)) totalQty["COUNT2"] = (totalQty["COUNT2"] || 0) + COUNT2.quantity;
- if (_.isNumber(COUNT3.quantity)) totalQty["COUNT3"] = (totalQty["COUNT3"] || 0) + COUNT3.quantity;
- if (_.isNumber(VERIFICATION.quantity)) totalQty["VERIFICATION"] = (totalQty["VERIFICATION"] || 0) + VERIFICATION.quantity;
+ for (const key of Object.keys(teams) as (keyof typeof teams)[]) {
+ const qty = teams[key]?.quantity;
- if (_.isNumber(VERIFICATION.quantity)) verificationCounter++;
+ if (_.isNumber(qty)) {
+ totalQty[key] = (totalQty[key] ?? 0) + qty;
+
+ if (key === "VERIFICATION") {
+ verificationCounter++;
+ }
+ }
+ }
}
- const product = await prisma.product.findFirst({ where: { id: parseInt(params.productId) } });
- if (!product) return;
+ const product = await prisma.product.findFirst({
+ where: { id: parseInt(params.productId) },
+ });
+
+ if (!product) {
+ return NextResponse.json({ message: "Product not found" }, { status: 404 });
+ }
const onhandQty = product.onhandQty;
- // const differenceQty = product.differenceQty
- const allQty = totalQty["COUNT1"] + totalQty["COUNT2"] + totalQty["COUNT3"] + totalQty["VERIFICATION"];
- const differenceQty = onhandQty - allQty;
- // const allQty = onhandQty + differenceQty
- const zeroCount1: boolean = totalQty["COUNT1"] === 0;
- const zeroCount2: boolean = totalQty["COUNT2"] === 0;
- const zeroCount3: boolean = totalQty["COUNT3"] === 0;
-
- if (verificationCounter > 0){
- isDifferent = false
- } else {
- const conditional = {
- verificationCheckAll: verificationCounter > 0 && verificationCounter === stockOpnames.length,
- // anyCountEqWithOnhand: [totalQty['COUNT1'], totalQty['COUNT2'], totalQty['COUNT3']].includes(onhandQty),
- anyCountEqWithOnhand: (totalQty["COUNT1"] === onhandQty && zeroCount2 && zeroCount3) || (totalQty["COUNT2"] === onhandQty && zeroCount3) || (totalQty["COUNT3"] === onhandQty),
- anyCountEqWithAllQty: [totalQty["COUNT1"], totalQty["COUNT2"], totalQty["COUNT3"]].includes(allQty),
- count1EqWithCount2: totalQty["COUNT1"] !== 0 && totalQty["COUNT2"] !== 0 && totalQty["COUNT1"] === totalQty["COUNT2"] && totalQty["COUNT3"] === null && totalQty["COUNT1"] !== onhandQty,
- count1EqWithCount3: totalQty["COUNT1"] !== 0 && totalQty["COUNT3"] !== 0 && totalQty["COUNT1"] === totalQty["COUNT3"],
- count2EqWithCount3: totalQty["COUNT2"] !== 0 && totalQty["COUNT3"] !== 0 && totalQty["COUNT2"] === totalQty["COUNT3"],
- };
- if (conditional.verificationCheckAll || conditional.anyCountEqWithOnhand || conditional.count1EqWithCount2 || conditional.count1EqWithCount3 || conditional.count2EqWithCount3) {
+ let isDifferent = true;
+
+ const countValues = [
+ totalQty.COUNT1,
+ totalQty.COUNT2,
+ totalQty.COUNT3,
+ ].filter((v): v is number => v !== null);
+ // SPECIAL RULE:
+ // Kalau onhand = 0 dan ada salah satu tim input 0 → dianggap tidak selisih
+ if (onhandQty === 0 && countValues.includes(0)) {
isDifferent = false;
- } else {
- isDifferent = true;
- }
}
- for (const opname of stockOpnames) {
- let { COUNT1, COUNT2, COUNT3, VERIFICATION } = opname;
-
- const count1 = _.isNumber(COUNT1.quantity) ? COUNT1.quantity : 0;
- const count2 = _.isNumber(COUNT2.quantity) ? COUNT2.quantity : 0;
- const count3 = _.isNumber(COUNT3.quantity) ? COUNT3.quantity : 0;
-
- const detailCondition = {
- verificationCheckAll: _.isNumber(VERIFICATION.quantity),
- anyCountEqWithOnhand: (totalQty["COUNT1"] === onhandQty && zeroCount2 && zeroCount3) || (totalQty["COUNT2"] === onhandQty && zeroCount3) || (totalQty["COUNT3"] === onhandQty),
- count1EqWithCount2: totalQty["COUNT3"] === 0 && count1 === count2,
- // count1EqWithCount3: count1 == count3,
- count1EqWithCount3: count1 != 0 && count1 === count3,
- count2EqWithCount3: totalQty["COUNT2"] !== 0 && totalQty["COUNT3"] !== 0 && count2 === count3,
- // count3EqWithCount1_2: (COUNT3.quantity !== COUNT1.quantity) && (COUNT3.quantity !== COUNT2.quantity) && (COUNT1.quantity === COUNT2.quantity) && (COUNT3.quantity !== onhandQty)
- };
-
- if (detailCondition.verificationCheckAll || detailCondition.anyCountEqWithOnhand || detailCondition.count1EqWithCount2 || detailCondition.count1EqWithCount3 || detailCondition.count2EqWithCount3) {
- isDifferent = false;
- } else {
- isDifferent = true;
- break;
- }
+ const uniqueCounts = [...new Set(countValues)];
+
+ const verificationExists = verificationCounter > 0;
+ if (verificationExists) {
+ isDifferent = false;
}
+ // SPECIAL RULE
+ else if (onhandQty === 0 && countValues.includes(0)) {
+ isDifferent = false;
+ } else if (countValues.length === 1) {
+ isDifferent = countValues[0] !== onhandQty;
+ } else if (uniqueCounts.length === 1) {
+ isDifferent = uniqueCounts[0] !== onhandQty;
+ } else {
+ isDifferent = true;
+ }
- const payload = {
+ // =============================
+ // 5️⃣ UPDATE PRODUCT
+ // =============================
+ await prisma.product.update({
where: { id: product.id },
data: { isDifferent },
- };
-
- await prisma.product.update(payload);
+ });
- return NextResponse.json(payload);
+ return NextResponse.json({
+ data: {
+ productId: product.id,
+ totalQty,
+ isDifferent,
+ },
+ });
}